package com.tanhua.dubbo.api;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tanhua.dubbo.mappers.*;
import com.tanhua.model.db.*;
import com.tanhua.model.vo.OptionsVo;
import com.tanhua.model.vo.QuestionsVo;
import com.tanhua.model.vo.TestSoulReportVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;

import javax.annotation.Resource;
import java.util.*;

@DubboService
public class TestSoulApiImpl implements TestSoulApi{
    @Resource
    private TestsoulMapper testsoulMapper;

    @Resource
    private QuestionsMapper questionsMapper;

    @Resource
    private OptionsMapper optionsMapper;

    @Resource
    private SubmitTheQuestionnaireMapper submitTheQuestionnaireMapper;

    @Resource
    private TestSoulReportMapper testSoulReportMapper;

    /**
     * 随机取出一套问卷
     *
     * @param testsoulGrau
     * @return
     */
    @Override
    public Testsoul findTestSoul(String testsoulGrau, Testsoul questionnaire) {
        // 1、根据等级查询问卷
        Random random = new Random();
        // 设置查询条件-----按照等级查询
        QueryWrapper<Testsoul> testSoulQuery = new QueryWrapper<>();
        testSoulQuery.eq("name",testsoulGrau);
        List<Testsoul> testsouls = testsoulMapper.selectList(testSoulQuery);
        // 设置随机数
        if(CollUtil.isEmpty(testsouls)){
            return null;
        }
        int number = random.nextInt(testsouls.size());
        // 随机抽取一套问卷
        Testsoul testSoul = testsouls.get(number);

        //2、根据问卷id，查询问卷题目，查询十个
        //获取问卷id
        Long testsoulId = testSoul.getId();
        //设置问卷题目查询条件
        QueryWrapper<Questions> questionsQuery = new QueryWrapper<>();
        questionsQuery.eq("testsoul_id",testsoulId);
        //设置问卷题目查询分页参数
        Page<Questions> questionsPage = new Page<>(1, 10);
        //查询问卷题目，十个
        List<Questions> questions = questionsMapper.selectPage(questionsPage, questionsQuery).getRecords();

        //3、根据问卷题目id，查询问卷题目选项
        List<QuestionsVo> questionsVos = new ArrayList<>();
       if(!CollUtil.isEmpty(questions)){
           for (Questions question : questions) {
               List<OptionsVo> optionsVos = new ArrayList<>();
               //根据问卷题目id，进行查询
               QueryWrapper<Options> optionsQuery = new QueryWrapper<>();
               optionsQuery.eq("questions_id",question.getId());
               List<Options> options = optionsMapper.selectList(optionsQuery);
//               List<Options> options = null;
              if(!CollUtil.isEmpty(options)){
                  //遍历options，将options对象转换成OptionsVo
                  for (Options option : options) {
                      optionsVos.add(OptionsVo.init(option));
                  }
              }
               question.setOptions(optionsVos);
               //将Questions转化成QuestionsVo对象，并放入questionsVos集合中
               questionsVos.add(QuestionsVo.init(question));
           }
       }
        testSoul.setQuestions(questionsVos);

       //4、查看问卷分数，如果分数大于60，解锁下一问卷
        if(questionnaire != null){
            unlockQuestionnaire(testSoul,questionnaire);
        }

        //5、返回结果
        return testSoul;
    }

    /**
     * 查看问卷分数，如果分数大于60，解锁下一问卷
     */
    private void unlockQuestionnaire(Testsoul questionnaireLow, Testsoul questionnaireLater) {
        //1、根据问卷report_id，查询te_submit_the_questionnaire中的achievement
        if(StringUtils.isEmpty(questionnaireLow.getReportId())){
            return;
        }
        SubmitTheQuestionnaire submitTheQuestionnaire = submitTheQuestionnaireMapper.selectById(questionnaireLow.getReportId());
        Integer achievement = submitTheQuestionnaire.getAchievement();
        //2、判断成绩是否大于60
        if(achievement > 60){
            //2-1、设置Testsoul的isLock值为0
            questionnaireLater.setIsLock(0);
            //2-2、根据id更改Testsoul数据
            testsoulMapper.updateById(questionnaireLater);

        }
    }


    /**
     * 将数据计算并保存到数据库中，并根据分数设置用户的类型；
     * @param answers
     * @return
     */
    @Override
    public String calculateScore(CalculateScore answers,Long userId) {
        int count = 0;

        //1、获取用户试题以及答案
        List<QuestionsAndOptions> questionsAndOptions = answers.getAnswers();
        Long questionId = Long.valueOf(questionsAndOptions.get(0).getQuestionId());
        //2、循环集合
        for (QuestionsAndOptions questionsAndOption : questionsAndOptions) {
            //2-1、将前端传递的用户id转换为Long类型
            Long optionId = Long.valueOf(questionsAndOption.getOptionId());
            //2-2、根据id查询tb_options数据库中的分数
            Options options = optionsMapper.selectById(optionId);
            //2-3、计算分数
            count += options.getQuestionScore();
        }
        //3、构建数据
        SubmitTheQuestionnaire submitTheQuestionnaire = new SubmitTheQuestionnaire();
        submitTheQuestionnaire.setUserId(userId);
        submitTheQuestionnaire.setAchievement(count);
        submitTheQuestionnaire.setUserType(measuringTheSoul(count));
        //4、将结果保存到数据库中
        submitTheQuestionnaireMapper.insert(submitTheQuestionnaire);
        //5、根据问卷id，更新testsoul数据库最新报告id
       /* UpdateWrapper<Testsoul> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",questionId).set("report_id",submitTheQuestionnaire.getId());
        testsoulMapper.update(null,updateWrapper);*/
       //5、根据试题编号查询
        Questions questions = questionsMapper.selectById(questionId);
        testsoulMapper.updateTestsoul(submitTheQuestionnaire.getId(),questions.getTestsoulId());
        //6、取出答卷id，转换成String类型并返回
        return submitTheQuestionnaire.getId().toString();
    }

    /**
     * 查询用户灵魂类型
     * @param id
     * @return
     */
    @Override
    public SubmitTheQuestionnaire findById(String id) {
        //调用mapper进行查询，
        return submitTheQuestionnaireMapper.selectById(Long.valueOf(id));
    }

    /**
     * 查询用户灵魂信息
     * @param userType   用户类型
     * @param achievement  总成绩
     * @return
     */
    @Override
    public TestSoulReportVO report(String userType, Integer achievement) {
        //调用方法，构造TestSoulReport
        TestSoulReport testSoulReport = build(userType,achievement);
        //构建Map集合
        String dimensionality = achievement + "%";
        Dimensions dimensions = new Dimensions();
        dimensions.setKey(userType);
        dimensions.setValue(dimensionality);
        ArrayList<Dimensions> dimensions1 = new ArrayList<>();
        dimensions1.add(dimensions);
        dimensions1.add(dimensions);
        dimensions1.add(dimensions);
        dimensions1.add(dimensions);
        TestSoulReportVO vo = TestSoulReportVO.init(testSoulReport,dimensions1);
        return vo;
    }

    /**
     * 查询用户的type相同的用户id列表
     * @param userType
     * @return
     */
    @Override
    public List<Long> findSameTypeIds(String userType) {
        List<Long> ids = submitTheQuestionnaireMapper.findIds(userType);
        return ids;
    }


    /**
     * 根据成绩测试灵魂信息
     */
    private static String measuringTheSoul(Integer grade){
        if(grade < 21){
            return "猫头鹰";
        }else if(grade < 40){
            return "白兔型";
        }else if(grade < 55){
            return "狐狸型";
        }else{
            return "狮子型";
        }
    }

    /**
     * 根据用户类型，查询对应的用户灵魂信息
     */
    private TestSoulReport build(String userType, Integer achievement) {
        TestSoulReport testSoulReport = null;

        UserTypeEnum userTypeEnum = UserTypeEnum.parse(userType);
        switch (userTypeEnum){
            case STRIGIFORMES:
                testSoulReport = testSoulReportMapper.selectTestSoulReport(1L);
                break;
            case COELHO:
                testSoulReport = testSoulReportMapper.selectTestSoulReport(2L);
                break;
            case FOX:
                testSoulReport = testSoulReportMapper.selectTestSoulReport(3L);
                break;
            case LION:
                testSoulReport = testSoulReportMapper.selectTestSoulReport(4L);
                break;
            default:
                break;
        }
        return testSoulReport;
    }
}
